package com.kehutong.charge.service.impl;

import com.kehutong.charge.entity.*;
import com.kehutong.charge.service.CommonService;
import com.kehutong.charge.util.CommonUtil;
import com.kehutong.charge.util.JDBCUtil;
import com.kehutong.charge.util.enums.*;
import com.kehutong.charge.vo.ChargeOperationLogExcelVO;
import com.kehutong.common.DailyUtil;
import com.kehutong.common.DoveClient;
import com.kehutong.common.Java8TimeUtils;
import com.kehutong.common.constant.CommonConstant;
import com.kehutong.common.entity.Root;
import com.kehutong.common.errcode.Assert;
import com.kehutong.common.errcode.Result;
import com.kehutong.common.excel.tool.ExcelTool;
import com.kehutong.common.util.ListUtils;
import org.coraframework.bean.Beans;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: kht
 * @description: CommonServiceImpl
 * @author: joneron
 * @create: 2021/7/12
 **/
@WebService("/charge/common/service")
public class CommonServiceImpl implements CommonService {

    private static final Logger logger = LoggerFactory.getLogger(CommonServiceImpl.class);

    @Inject
    private DoveClient doveClient;
    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private ExcelTool excelTool;
    @Inject
    CommonService commonService;


    @Override
    public Page<ChargeOperationLog> findLoggerList(JSONObject jsonObject) {

        FindPage<ChargeOperationLog> find = jdbcSession.findPage(ChargeOperationLog.class)
                .eq(jsonObject,"functionNo")
                .eq(jsonObject,"optFunction")
                .eq(jsonObject,"optModule");

        // 处理时间
        JDBCUtil.between(jsonObject, find, "createTime");

        find.order("createTime", "desc").page(jsonObject);
        return find.exe();
    }


    @Override
    public void pageExport(HttpServletRequest req, HttpServletResponse resp, JSONObject jsonObject) {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", ExcelTool.MAX_ROWS);
        List<ChargeOperationLog> list = findLoggerList(jsonObject).getList();
        Assert.notEmpty(list,"导出失败！未找到相关的操作记录.");
        List<ChargeOperationLogExcelVO> logList = ListUtils.copyBeanList(list, ChargeOperationLogExcelVO::new);
        excelTool.excelDownload(req,resp,logList,"常规收费账单操作记录导出");
    }


    @Override
    public Object insetLogger(String functionNo,String module, String function,
                              String billState,String status, String desc,String optName) {

        ChargeOperationLog logs = Pool.newInstance(ChargeOperationLog.class);
        logs.setOpStatus(status);
        logs.setOptFunction(function);
        logs.setOptDesc(desc);
        logs.setOptModule(module);
        logs.setCreateName(optName);
        logs.setBillState(billState);
        logs.setFunctionNo(functionNo);

        return jdbcSession.insert(logs);
    }

    @Override
    public Object findFeeConfigList(JSONObject jsonObject) {
        //查询一级的所有数据
        String communityNo = jsonObject.getString("communityNo");
        List<ChargeTypeConfig> residentHouses = jdbcSession.findArray(ChargeTypeConfig.class)
                .eq("deleted", false)
                .eq("status",true)
                .eq("communityNo",communityNo)
                .exe();
        if (Objects.isEmpty(residentHouses)) {
            residentHouses = jdbcSession.findArray(ChargeTypeConfig.class)
                    .eq("deleted", false)
                    .eq("status",true)
                    .eq("communityNo",CommonConstant.DEFAULT_COMMUNITY_NO)
                    .exe();
        }

        List<String> residentNos = residentHouses.stream().map(ChargeTypeConfig::getId).collect(Collectors.toList());

        List<ChargeProjectConfig> residents = jdbcSession.findArray(ChargeProjectConfig.class)
                .in("feeTypeNo", residentNos)
                .eq("communityNo",communityNo)
                .eq("deleted",false)
                .eq("status",1)
                .exe();
        if (Objects.isEmpty(residents)) {
            residents = jdbcSession.findArray(ChargeProjectConfig.class)
                    .in("feeTypeNo", residentNos)
                    .eq("communityNo",CommonConstant.DEFAULT_COMMUNITY_NO)
                    .eq("deleted",false)
                    .eq("status",1)
                    .exe();
        }

        List<JSONObject> result = new ArrayList<>();
        for (ChargeTypeConfig type: residentHouses) {
            JSONObject json = new JSONObject();
            json.put("name", type.getFeeTypeName());
            json.put("id", type.getId());

            List<JSONObject> list = new ArrayList<>();
            residents.forEach(item -> {
                if(Objects.equal(item.getFeeTypeNo(), type.getId())){
                    JSONObject temp = new JSONObject();
                    temp.put("id", item.getId());
                    temp.put("name", item.getProjectFeeName());
                    list.add(temp);
                }
            });
            json.put("data", list);
            result.add(json);
        }

        return result;
    }

    @Override
    public BigDecimal calcFeeCommon(ChargeProjectConfig config,BigDecimal number,String billNO) {


        BigDecimal total = BigDecimal.ZERO; //总金额
        BigDecimal price = config.getPrice(); //单价
        if (ChargeFeeEnum.FEE_PRICE == config.getFeeEnum()) {
            return config.getPrice();
        }

        switch (config.getCalcEnum()) {
            case MODE_USAGE: //按用量
                total = calcType(config,number,billNO);
                break;
            case MODE_AREA: //按面积
                total = calcType(config,number,billNO);
                break;
            case MODE_HOUSE: //按户收费
                total = price;
                break;
            case MODE_CAR: //按车位收费
                total = price;
                break;
        }

        return total;
    }

    @Override
    public Object updateDict(JSONObject jsonObject) {

        JSONArray array = jsonObject.getJSONArray("dictList");
        if(null == array){
            return Result.error(2110,"提交的数据不能为空！");
        }

        List<ChargeDict> dictList = jdbcSession.findArray(ChargeDict.class).exe();
        if(null == dictList || dictList.size() == 0 ){
            for (int i = 0; i < array.size(); i++) {
                JSONObject json = array.getJSONObject(i);
                ChargeDict dict = Pool.newInstance(ChargeDict.class);
                dict.setDictKey(json.getString("dictKey"));
                dict.setDictValue(json.getString("dictValue"));
                dict.setCreateName(json.getString("userName"));
                jdbcSession.insert(dict);
            }
        }else{
            for (int i = 0; i < array.size(); i ++) {
                JSONObject json = array.getJSONObject(i);
                ChargeDict dict = dictList.get(i);
                dict.setDictValue(json.getString("dictValue"));
                dict.setCreateName(json.getString("userName"));
                jdbcSession.updateById(dict);
            }
        }
        return 0;
    }

    @Override
    public Object findDict(JSONObject jsonObject) {

        return jdbcSession.findArray(ChargeDict.class).exe();
    }

    @Override
    public void updateOrderTask() throws Exception {


        JSONArray array = getCorps();
        if(Objects.nonEmpty(array)) {
            for (Object obj : array) {
                JSONObject corp = (JSONObject) obj;

                String corpId = corp.getString("id");
                if (corpId.equals(Root.ROOT_ID)) {
                    continue;
                }
                int nums = 0;
                try {
                    ThreadLocalCache.current().setCorpId(corpId);

                    //查询所有未缴费的订单，时间超过设置的时间（默认半个小时）
                    List<ChargeOrderManage> orderList = jdbcSession.findArray(ChargeOrderManage.class)
                            .eq("orderStatus", ChargeOrderStatusEnum.ORDER_WAIT_PAY).exe();

                    logger.info("订单定时任务执行开始！数据库：{},数量：{}",corpId,orderList.size());

                    for (int i = 0; i < orderList.size(); i++) {

                        ChargeOrderManage manage = orderList.get(i);

                        //查询临时订单配置
                        ChargeOrderConfig dict = jdbcSession.findOne(ChargeOrderConfig.class)
                                .eq("communityNo", manage.getCommunityNo())
                                .eq("status", true).exe();

                        long minute = 30; //默认30分钟

                        if(null != dict){ //则取默认的
                            minute = Long.parseLong(dict.getCgOrderMinute());
                        }

                        logger.info("订单定时任务执行开始！配置时间：{}",minute);

                        if(minute == 0){ //没有设置或者关闭状态，等于0，则直接关闭
                            manage.setOrderStatus(ChargeOrderStatusEnum.ORDER_CLOSE); //订单设置作废
                            // 修改订单状态
                            jdbcSession.updateById(manage);

                            commonService.insetLogger(manage.getOrderNo(),
                                    ChargeLogEnum.LOG_CHARGE_ORDER_COM.getDesc(),
                                    "订单功能",
                                    ChargeOrderStatusEnum.ORDER_CLOSE.getDesc(),
                                    ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "自动关闭订单", "系统");
                        }else {
                            //1、订单创建秒数
                            long create = DailyUtil.fromTimeStamp(manage.getCreateTime()).getTime() / 1000;
                            //2、获取当前时间秒数
                            long currDate = System.currentTimeMillis() / 1000;
                            //3、计算时间差
                            long num = currDate - create;
                            //4、获取设置的时间(分钟)
                            long ttm = minute * 60;

                            if (ttm > 0 && ttm <= num) { //0则订单不限制,大于设置的时间，则订单超时
                                manage.setOrderStatus(ChargeOrderStatusEnum.ORDER_CLOSE); //订单设置作废
                                // 修改订单状态
                                jdbcSession.updateById(manage);
                                nums++;
                                commonService.insetLogger(manage.getOrderNo(),
                                        ChargeLogEnum.LOG_CHARGE_ORDER_COM.getDesc(),
                                        "订单功能",
                                        ChargeOrderStatusEnum.ORDER_CLOSE.getDesc(),
                                        ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "自动关闭订单", "系统");
                            }
                        }
                    }
                }catch (Exception ex){
                    logger.error("订单定时任务执行错误！",ex);
                }

                logger.info("订单定时任务执行结束！数据库：{},数量：{}",corpId,nums);
            }
        }

    }

    @Override
    public Object updateOrderInterimTask() throws Exception {

        JSONArray array = getCorps();
        if(Objects.nonEmpty(array)) {
            for (Object obj : array) {
                JSONObject corp = (JSONObject) obj;

                String corpId = corp.getString("id");
                if (corpId.equals(Root.ROOT_ID)) {
                    continue;
                }

                try {
                    ThreadLocalCache.current().setCorpId(corpId);

                    //查询所有未缴费的订单，时间超过设置的时间（默认半个小时）
                    List<ChargeOrderInterim> orderList = jdbcSession.findArray(ChargeOrderInterim.class)
                            .eq("orderStatus", ChargeOrderStatusEnum.ORDER_WAIT_PAY).exe();

                    logger.info("临时订单定时任务执行开始！数据库：{},数量：{}",corpId,orderList.size());

                    for (int i = 0; i < orderList.size(); i++) {

                        ChargeOrderInterim manage = orderList.get(i);

                        //查询临时订单配置
                        ChargeOrderConfig dict = jdbcSession.findOne(ChargeOrderConfig.class)
                                .eq("communityNo", manage.getCommunityNo())
                                .eq("status", true).exe();

                        long minute = 30; //默认30分钟

                        if(null != dict){ //则取默认的
                            minute = Long.parseLong(dict.getCgOrderMinute());
                        }

                        logger.info("临时订单定时任务执行开始！配置时间：{}",minute);

                        if(minute == 0){ //没有设置或者关闭状态，等于0，则直接关闭
                            manage.setOrderStatus(ChargeOrderStatusEnum.ORDER_CLOSE); //订单设置作废
                            // 修改订单状态
                            jdbcSession.updateById(manage);

                            commonService.insetLogger(manage.getInterimBillNo(),
                                    ChargeLogEnum.LOG_CHARGE_ORDER_INT.getDesc(),
                                    "临时订单功能",
                                    ChargeOrderStatusEnum.ORDER_CLOSE.getDesc(),
                                    ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "自动关闭订单", "系统");
                        }else{
                            //1、订单创建秒数
                            long create = DailyUtil.fromTimeStamp(manage.getCreateTime()).getTime() / 1000;
                            //2、获取当前时间秒数
                            long currDate = System.currentTimeMillis() / 1000;
                            //3、计算时间差
                            long num = currDate - create;
                            //4、获取设置的时间(分钟)
                            long ttm = minute * 60;

                            if (ttm > 0 && ttm <= num) { //0则订单不限制,大于设置的时间，则订单超时
                                manage.setOrderStatus(ChargeOrderStatusEnum.ORDER_CLOSE); //订单设置作废
                                // 修改订单状态
                                jdbcSession.updateById(manage);

                                commonService.insetLogger(manage.getInterimBillNo(),
                                        ChargeLogEnum.LOG_CHARGE_ORDER_INT.getDesc(),
                                        "临时订单功能",
                                        ChargeOrderStatusEnum.ORDER_CLOSE.getDesc(),
                                        ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(),"自动关闭订单", "系统");
                            }
                        }
                    }
                }catch (Exception ex){
                    logger.error("临时订单定时任务执行问题！",ex);
                }
            }
        }

        return Result.success();
    }

    /**
     * 获取所有企业信息
     * @return
     * @throws Exception
     */
    private JSONArray getCorps() throws Exception {
        JSONObject result = doveClient.post("/admin/service/corp/list",(http)->{});

        if (result.getIntValue("code") == 200) {
            return result.getJSONArray("data");
        }

        return null;
    }

    @Override
    public Object updatePenaltyTask() throws Exception {

        String today = Java8TimeUtils.dateShort();

        JSONArray array = getCorps();
        if(Objects.nonEmpty(array)) {

            logger.info("违约金定时任务公司集合：{}",array.size());

            for (Object obj : array) {
                JSONObject corp = (JSONObject) obj;

                String corpId = corp.getString("id");
                if (corpId.equals(Root.ROOT_ID)) {
                    continue;
                }
                int num = 0;

                try{
                    ThreadLocalCache.current().setCorpId(corpId);

                    logger.info("日期：{},违约金定时任务执行开始！数据库：{}",today,corpId);

                    //先判断今天是否有生成违约金
                    List<ChargePenaltyOrder> penaltyOrders = jdbcSession.findArray(ChargePenaltyOrder.class).like("createTime",today).exe();

                    if(Objects.nonEmpty(penaltyOrders)){
                        logger.error("违约金定时任务：{}当天违约金定时任务已经生成！公司：{}",today,corpId);
                        continue;
                    }

                    //1、查询未缴费的账单，大于等于违约时间
                    List<ChargeBillItems> billItems = jdbcSession.findArray(ChargeBillItems.class)
                            .eq("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID)
                            .minEq("penaltyDate", Java8TimeUtils.dateShort()).exe();

                    for (int i = 0; i < billItems.size(); i++) {

                        ChargeBillItems items = billItems.get(i);
                        ChargeHouseConfig houseConfig = jdbcSession.findOne(ChargeHouseConfig.class)
                                .eq("deleted", false)
                                .eq("houseNo",items.getHouseNo())
                                .exe();
                        if(null == houseConfig){
                            logger.error("违约金定时任务：房屋：{}，没有找到房屋收费配置项！",items.getBillAddress());
                            continue;
                        }
                        /**ChargeTypeConfig typeConfigs = jdbcSession.findOne(ChargeTypeConfig.class)
                                .eq("deleted", false)
                                .eq("id",items.getChargeTypeConfigId())
                                .exe();*/
                        //查询费用配置项
                        List<ChargeHouseSet> houseSetList = jdbcSession.findArray(ChargeHouseSet.class)
                                .eq("deleted", false)
                                .eq("chargeHouseNo",houseConfig.getId())
                                .eq("feeTypeNo",items.getChargeTypeConfigId())
                                .exe();

                        if (Objects.isEmpty(houseSetList)) {
                            logger.error("违约金定时任务：房屋：{}，没有找到资产收费配置项！",items.getBillAddress());
                            continue;
                        }

                        //2、获取违约配置，并计算违约值
                        ChargeProjectConfig config = jdbcSession.findOne(ChargeProjectConfig.class)
                                .eq("status", true)
                                .eq("id", houseSetList.get(0).getProjectFeeNo()).exe();

                        if (null == config || !config.isLateFee()) { //没有开启违约金
                            logger.error("违约金定时任务：该收费项目-{}，没有设置违约金或没开启！",houseSetList.get(0).getProjectFeeName());
                            continue;
                        }

                        BigDecimal unitAmount = BigDecimal.ZERO;
                        //使用百分比或者千分比
                        if (config.getLateFeeScale().equals(PriceUnitEnum.PRICE_PERCENTAGE)) {
                            unitAmount = new BigDecimal(config.getLateFeeNum()).divide(new BigDecimal(100));
                        } else {
                            unitAmount = new BigDecimal(config.getLateFeeNum()).divide(new BigDecimal(1000));
                        }
                        //计算违约金
                        BigDecimal amount = items.getPayableAmount().multiply(unitAmount);

                        logger.info("违约金定时任务：ItemBillNo:{},账单金额：{}，配置违约比例：{}， 违约金额:{}",
                                items.getItemBillNo(),items.getPayableAmount(),config.getLateFeeNum(),amount);

                        //3、添加违约记录
                        ChargePenaltyOrder penaltyOrder = Pool.newInstance(ChargePenaltyOrder.class);
                        penaltyOrder.setPenaltyNo(CommonUtil.generateRandom("WY"));
                        penaltyOrder.setItemBillNo(items.getItemBillNo());
                        penaltyOrder.setHouseBillNo(items.getHouseBillNo());
                        penaltyOrder.setPenaltyAmount(items.getPayableAmount());
                        penaltyOrder.setPayableAmount(amount);
                        penaltyOrder.setPenaltyUnit(config.getLateFeeUnit());
                        penaltyOrder.setPenaltyScale(config.getLateFeeScale());
                        penaltyOrder.setLateFeeNum(config.getLateFeeNum());
                        penaltyOrder.setPenaltyDate(items.getPenaltyDate());
                        penaltyOrder.setOwnerNo(items.getUserNo());
                        penaltyOrder.setUserName(items.getChargeName());
                        penaltyOrder.setResidentsType(items.getResidentsType());
                        penaltyOrder.setCommunityNo(items.getCommunityNo());
                        penaltyOrder.setHouseNo(items.getHouseNo());
                        penaltyOrder.setChargeAddress(items.getBillAddress());
                        penaltyOrder.setCommunityName(items.getCommunityName());
                        penaltyOrder.setBillStatus(ChargeBillStatusEnum.BILL_WAIT_PAID);
                        penaltyOrder.setBillYearMonth(items.getBillYearMonth());

                        jdbcSession.insert(penaltyOrder);

                        //修改金额
                        Integer dayNum = DailyUtil.intervalDays(Java8TimeUtils.subStrDate(items.getPenaltyDate()));
                        items.setPenaltyDays(dayNum); //修改违约天数
                        BigDecimal amount1 = items.getPenaltyAmount();
                        amount1 = amount1.add(amount);
                        items.setPenaltyAmount(amount1);
                        jdbcSession.updateById(items);

                        //4、更新违约天数和违约金额
                        ChargeBillHouse house = jdbcSession.findOne(ChargeBillHouse.class)
                                .eq("houseBillNo", items.getHouseBillNo())
                                .eq("billStatus",ChargeBillStatusEnum.BILL_WAIT_PAID).exe();

                        //Integer dayNum2 = DailyUtil.intervalDays(Java8TimeUtils.subStrDate(items.getPenaltyDate()));
                        house.setPenaltyDays(dayNum); //修改违约天数
                        BigDecimal amount2 =house.getPenaltyAmount();
                        amount2 = amount2.add(amount);
                        house.setPenaltyAmount(amount2); //违约金额
                        BigDecimal amount3 =house.getBillAmount();
                        amount3 = amount3.add(amount);
                        house.setBillAmountUnPaid(amount3);
                        house.setBillAmount(amount3);
                        jdbcSession.updateById(house);

                        //判断改账单是否已经存在违约金，只能有一条
                        ChargeBillItems billItems11 = jdbcSession.findOne(ChargeBillItems.class)
                                .eq("houseBillNo",items.getHouseBillNo())
                                .eq("billYearMonth",items.getBillYearMonth())
                                .eq("feeTypeName","违约金").exe();

                        logger.info("违约金定时任务：生成违约金--》houseBillNo:{},billYearMonth：{}， 违约金额:{}",
                                items.getHouseBillNo(),items.getBillYearMonth(),amount);

                        //类目账单存在一条违约金，则修改金额
                        if(null == billItems11){
                            //数据复制
                            ChargeBillItems billItems1 = Pool.newInstance(ChargeBillItems.class);
                            Beans.from(items).to(billItems1).exclude("id").igornNull().copy();

                            billItems1.setFeeTypeName("违约金");
                            billItems1.setFeeTypeNo("000000000000000000");
                            billItems1.setMeterTypeName("违约金");
                            billItems1.setMeterTypeNo("000000000000000000");
                            billItems1.setMeterClassifyName("违约金");
                            billItems1.setMeterClassifyNo("000000000000000000");
                            String billNO = CommonUtil.generateRandom("LM");
                            billItems1.setItemBillNo(billNO);
                            billItems1.setChargeStatus(ChargeBillStatusEnum.BILL_UN_PAID);
                            billItems1.setBillStatus(ChargeBillStatusEnum.BILL_WAIT_PAID);
                            billItems1.setPenaltyAmount(amount);
                            billItems1.setBillAmount(amount);
                            billItems1.setPayableAmount(amount);
                            billItems1.setUsageNumber(null);
                            billItems1.setLastTimeNumber(null);
                            billItems1.setTimeNumber(null);

                            jdbcSession.insert(billItems1);
                        }else{
                            //修改金额
                            BigDecimal amount11 = billItems11.getPayableAmount();
                            amount11 = amount11.add(amount);
                            billItems11.setPenaltyAmount(amount11);
                            billItems11.setBillAmount(amount11);
                            billItems11.setPayableAmount(amount11);
                            billItems11.setPenaltyDays(dayNum);
                            jdbcSession.updateById(billItems11);
                        }

                        num ++;
                    }

                }catch (Exception ex){
                    logger.error("违约金定时任务处理问题!",ex);
                }

                logger.info("日期：{},违约金定时任务执行结束！处理数量：{}",today,num);
            }
        }

        return Result.success();
    }

    @Override
    public Object addMeterDataTask() {

        //生成前先删除旧数据
        List<MeterReadStatist> statists = jdbcSession.findArray(MeterReadStatist.class).eq("readYearMonth",DailyUtil.get_yyyy_MM()).exe();
        for (int i = 0; i < statists.size(); i++) {
            jdbcSession.deleteById(MeterReadStatist.class,statists.get(i).getId());
        }

        //查询已绑定的仪表
        List<MeterManage> meterManageList = jdbcSession.findArray(MeterManage.class)
                .eq("deleted", false).exe();

        for (int i = 0; i < meterManageList.size(); i++) {

            MeterManage meterManage = meterManageList.get(i);
            MeterReadStatist statist = Pool.newInstance(MeterReadStatist.class);
            statist.setMeterNo(meterManage.getMeterNo());
            statist.setMeterTypeNo(meterManage.getMeterTypeNo());
            statist.setMeterTypeName(meterManage.getMeterTypeName());
            statist.setMeterClassifyNo(meterManage.getMeterClassifyNo());
            statist.setMeterClassifyName(meterManage.getMeterClassifyName());
            statist.setMeterAddress(meterManage.getMeterAddress());
            statist.setReadYearMonth(DailyUtil.get_yyyy_MM());
            statist.setCommunityName(meterManage.getCommunityName());
            statist.setCommunityNo(meterManage.getCommunityNo());
            statist.setHouseNo(meterManage.getHouseNo());
            //每个月最后一天
            String dates = DailyUtil.get_yyyy_MM()+"-"+DailyUtil.getMaxOfMonth(new Date());
            statist.setStartTime(DailyUtil.get_yyyy_MM()+"-1");
            statist.setEndTime(dates);
            statist.setFeeStatus("1");  //1.未抄表，2.已抄表
            statist.setReadStatus("1"); //1.待计费，2.已计费
            statist.setCreateName("system");

            jdbcSession.insert(statist);
        }

        return 0;
    }



    /**
     * 收费方式计算
     * @param useNumber 使用量
     */
    private BigDecimal calcType(ChargeProjectConfig config,BigDecimal useNumber,String billNO){

        //默认金额
        BigDecimal total = BigDecimal.ZERO;
        BigDecimal price = config.getPrice(); //单价
        boolean bool = config.isGuarantee();//是否保底
        BigDecimal usagePrice = config.getUsagePrice();//保底价格
        BigDecimal usageEnd = config.getUsageEnd(); //保底范围

        switch (config.getFeeEnum()) {
            case FEE_UNIT_PRICE: //单价
                //判断是否有保底价,保底则获取保底价
                if(bool){ //保底
                    if(useNumber.compareTo(usageEnd) < 1){ //判断用量是否在范围内
                        total = usagePrice;
                    }else{
                        //单价 * 用量 = 总价
                        total = price.multiply(useNumber);
                    }
                }else {
                    total = price.multiply(useNumber);
                    //单价 * 用量 = 总价
                }
                break;
            case FEE_LADDER: //阶梯价
                //判断是否有保底价,保底则获取保底价
                if(bool){ //保底
                    if(useNumber.compareTo(usageEnd) < 1){ //判断用量是否在范围内
                        total = usagePrice;
                    }else{
                        total = calcLadderAmount(useNumber,config.getId(),billNO);
                    }
                }else {
                    total = calcLadderAmount(useNumber,config.getId(),billNO);
                }
                break;
            case FEE_PRICE: //一口价
                total = price;
                break;
        }
        return total;
    }

    /**
     * 计算阶梯价格
     * @param useNumber 使用量
     *  @param chargeProjectId 配置项id
     * @return
     */
    private BigDecimal calcLadderAmount(BigDecimal useNumber,String chargeProjectId,String billNO){

        //查询阶梯数据
        List<ChargeLadderConfig> ladderList = jdbcSession.findArray(ChargeLadderConfig.class)
                .eq("chargeProjectNo",chargeProjectId)
                .order("usageStart","asc").exe();

        //默认金额
        BigDecimal amount = BigDecimal.ZERO;
        BigDecimal amount2 = BigDecimal.ZERO;
        String uId = null;

        for (int i = 0; i < ladderList.size(); i++) {
            ChargeBillLadder billLadder = Pool.newInstance(ChargeBillLadder.class);
            ChargeLadderConfig config = ladderList.get(i);
            billLadder.setUsagePrice(config.getUsagePrice());
            billLadder.setUsageType(config.getUsageType());
            billLadder.setChargeProjectNo(config.getChargeProjectNo());
            billLadder.setItemBillNo(billNO);

            //配置阶段的用量
            BigDecimal sub = config.getUsageEnd().subtract(config.getUsageStart());

            useNumber = useNumber.subtract(sub);
            if(useNumber.compareTo(BigDecimal.ZERO) > -1){ //a大于等于b
                //用量 * 单价 = 总价
                amount = amount.add(sub.multiply(config.getUsagePrice()));
                billLadder.setTotalAmount(sub.multiply(config.getUsagePrice()));
                billLadder.setUsageNumber(sub);
                //添加阶梯费用项
                jdbcSession.insert(billLadder);

                amount2 = config.getUsagePrice();
                uId = billLadder.getId();
            }else{
                BigDecimal useOr = useNumber.add(sub);
                //用量 * 单价 = 总价
                amount = amount.add(useOr.multiply(config.getUsagePrice()));
                billLadder.setTotalAmount(useOr.multiply(config.getUsagePrice()));
                billLadder.setUsageNumber(useOr);

                //添加阶梯费用项
                jdbcSession.insert(billLadder);
                break;
            }
        }

        //最后一种
        if(useNumber.compareTo(BigDecimal.ZERO) == 1){ //a大于b
            ChargeBillLadder ladder = jdbcSession.findById(ChargeBillLadder.class,uId);
            ladder.setTotalAmount(ladder.getTotalAmount().add(useNumber.multiply(amount2)));
            ladder.setUsageNumber(ladder.getUsageNumber().add(useNumber));
            amount = amount.add(useNumber.multiply(amount2));
            jdbcSession.updateById(ladder);
        }

        return amount;
    }

}
